/**
 * Copyright (C) 2018-2022
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.modules.user.rest;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.api.YshopException;
import co.yixiang.constant.ShopConstants;
import co.yixiang.dozer.service.IGenerator;
import co.yixiang.modules.aop.ForbidSubmit;
import co.yixiang.modules.logging.aop.log.Log;
import co.yixiang.modules.user.domain.YxUser;
import co.yixiang.modules.user.service.YxUserService;
import co.yixiang.modules.user.service.dto.UserMoneyDto;
import co.yixiang.modules.user.service.dto.YxUserDto;
import co.yixiang.modules.user.service.dto.YxUserQueryCriteria;
import co.yixiang.modules.user.vo.OnlineUser;
import co.yixiang.utils.EncryptUtils;
import co.yixiang.utils.RedisUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author hupeng
 * @date 2019-10-06
 */
@Api(tags = "商城:会员管理")
@RestController
@RequestMapping("api")
public class MemberController {

    private final YxUserService yxUserService;
    private final RedisUtils redisUtils;
    @Autowired
    private IGenerator generator;

    public MemberController(YxUserService yxUserService, RedisUtils redisUtils) {
        this.yxUserService = yxUserService;
        this.redisUtils = redisUtils;
    }

    @Log("查看下级")
    @ApiOperation(value = "查看下级")
    @PostMapping(value = "/yxUser/spread")
    @PreAuthorize("hasAnyRole('admin','YXUSER_ALL','YXUSER_EDIT')")
    public ResponseEntity getSpread(@RequestBody YxUserQueryCriteria criteria) {
        return new ResponseEntity<>(yxUserService.querySpread(criteria.getUid(), criteria.getGrade()),
                HttpStatus.OK);
    }

    @ApiOperation(value = "查询所有用户")
    @GetMapping(value = "/getAllUserList")
    public ResponseEntity getAllUserList() {
        return new ResponseEntity<>(yxUserService.list(), HttpStatus.OK);
    }

    @ApiOperation(value = "查询用户")
    @GetMapping(value = "/yxUser")
    @PreAuthorize("hasAnyRole('admin','YXUSER_ALL','YXUSER_SELECT')")
    public ResponseEntity getYxUsers(YxUserQueryCriteria criteria, Pageable pageable) {
        return new ResponseEntity<>(yxUserService.queryAll(criteria, pageable), HttpStatus.OK);
    }


    @Log("修改用户")
    @ApiOperation(value = "修改用户")
    @PutMapping(value = "/yxUser")
    @PreAuthorize("hasAnyRole('admin','YXUSER_ALL','YXUSER_EDIT')")
    public ResponseEntity update(@Validated @RequestBody YxUser yxUser) throws Exception {
        if (StrUtil.isEmpty(yxUser.getShopName())) {
            throw new YshopException("请填写店家姓名");
        }
        if (StrUtil.isEmpty(yxUser.getSubCompany())) {
            throw new YshopException("请填写分公司");
        }
        if (StrUtil.isEmpty(yxUser.getShopCode())) {
            throw new YshopException("请填写店铺编码");
        }
        if (StrUtil.isEmpty(yxUser.getDepartName())) {
            throw new YshopException("请填写所属部门");
        }
        if (yxUser.getVisibleGoodsCategoryLevelList() == null) {
            throw new YshopException("请选择可见商品分类");
        }
//        if (ObjectUtil.isNotNull(yxUser.getHouseEffectiveStartTime())
//                || ObjectUtil.isNotNull(yxUser.getHouseEffectiveEndTime())
//                || ObjectUtil.isNotNull(yxUser.getHouseFullAddress())
//                || ObjectUtil.isNotNull(yxUser.getHouseAddressDetail())) {
//            if (ObjectUtil.isEmpty(yxUser.getHouseEffectiveStartTime())
//                    || ObjectUtil.isEmpty(yxUser.getHouseEffectiveEndTime())
//                    || ObjectUtil.isEmpty(yxUser.getHouseFullAddress())
//                    || ObjectUtil.isEmpty(yxUser.getHouseAddressDetail())) {
//                throw new YshopException("请完善用户的全部住房信息");
//            }
//        }

        List<String> visibleGoodsCategoryLevelList = yxUser.getVisibleGoodsCategoryLevelList();
        if (visibleGoodsCategoryLevelList != null && visibleGoodsCategoryLevelList.size() > 0) {
            yxUser.setVisibleGoodsCategoryLevel(visibleGoodsCategoryLevelList.stream()
                    .collect(Collectors.joining(",")));
        }
        YxUser user = yxUserService.getById(yxUser.getUid());
        //审核状态,2禁用3不通过，退出用户登录状态
        if (yxUser != null && (yxUser.getReviewStatus() == 2 || yxUser.getReviewStatus() == 3)) {
            List<OnlineUser> onlineUsers = this.getAllOnlineUser();
            for (OnlineUser onlineUser : onlineUsers) {
                if (onlineUser.getUserName().equals(user.getUsername())) {
                    String key = ShopConstants.YSHOP_APP_LOGIN_USER + user.getUsername() + ":" + EncryptUtils.desDecrypt(onlineUser.getKey());
                    redisUtils.del(key);
                    break;
                }
            }
        }
        yxUserService.saveOrUpdate(yxUser);
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

    @ForbidSubmit
    @Log("删除用户")
    @ApiOperation(value = "删除用户")
    @DeleteMapping(value = "/yxUser/{uid}")
    @PreAuthorize("hasAnyRole('admin','YXUSER_ALL','YXUSER_DELETE')")
    public ResponseEntity delete(@PathVariable Integer uid) {
        yxUserService.removeById(uid);
        return new ResponseEntity(HttpStatus.OK);
    }

    @ForbidSubmit
    @ApiOperation(value = "用户禁用启用")
    @PostMapping(value = "/yxUser/onStatus/{id}")
    public ResponseEntity onStatus(@PathVariable Long id, @RequestBody String jsonStr) {
        JSONObject jsonObject = JSON.parseObject(jsonStr);
        Integer status = jsonObject.getInteger("status");
        yxUserService.onStatus(id, status);
        return new ResponseEntity(HttpStatus.OK);
    }

    @ApiOperation(value = "修改余额")
    @PostMapping(value = "/yxUser/money")
    @PreAuthorize("hasAnyRole('admin','YXUSER_ALL','YXUSER_EDIT')")
    public ResponseEntity updatePrice(@Validated @RequestBody UserMoneyDto param) {
        yxUserService.updateMoney(param);
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

    @ApiOperation(value = "重置密码")
    @PostMapping(value = "/yxUser/resetPass")
    @PreAuthorize("hasAnyRole('admin','YXUSER_ALL','YXUSER_EDIT')")
    public ResponseEntity resetPass(@RequestBody JSONObject jsonObject) {
        yxUserService.resetPass(jsonObject);
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

    @Log("导出客户数据")
    @ApiOperation("导出客户数据")
    @GetMapping(value = "/yxUser/download")
    @PreAuthorize("hasAnyRole('admin','YXUSER_ALL','YXUSER_SELECT')")
    public void download(HttpServletResponse response, YxUserQueryCriteria criteria,
                         @RequestParam(name = "listContent") String listContent) throws IOException {
        if (StringUtils.isNotEmpty(listContent)) {
            List<String> idList = JSONArray.parseArray(listContent).toJavaList(String.class);
            criteria.setIds(idList);
        }
        yxUserService.download(generator.convert(yxUserService.queryAll(criteria), YxUserDto.class), response);
    }

    /**
     * 查询全部数据，不分页
     *
     * @return /
     */
    public List<OnlineUser> getAllOnlineUser() {
        List<String> keys = null;
        keys = redisUtils.scan(ShopConstants.YSHOP_APP_LOGIN_USER + "*");


        Collections.reverse(keys);
        List<OnlineUser> onlineUsers = new ArrayList<>();
        for (String key : keys) {
            OnlineUser onlineUser = (OnlineUser) redisUtils.get(key);
            onlineUsers.add(onlineUser);
        }
        onlineUsers.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime()));
        return onlineUsers;
    }

}
